package org.one.stone.soup.grfxML;

import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.mjdb.data.field.Field;
import org.one.stone.soup.mjdb.data.field.LockException;
import org.one.stone.soup.xml.XmlElement;
  /*
 * Copyright 2000-2001 Wet-Wired.com Ltd.,
 * Portsmouth England
 * All rights reserved.
 */

/**
	*
	* @author Nik Cross
*/
public  class DataActionSet extends DataAction implements ITag{
	public static String DEFAULT_ID="_ActionSet";

		DataString rule = new DataString(ProcessConstant.SET_EXCLUSIVE);

		DataStates group = new DataStates();
		DataStates oldGroup = null;

		private int _ruleCode = ProcessConstant.SET_EXCLUSIVE_CODE;
public DataActionSet(DataNode parent) {
	super(parent);

	try{
		setId(DEFAULT_ID,this);
	}
	catch(LockException le){} //Dummy catch
}
public void buildFromgrfxML(XmlElement xml)
{


	String name = xml.getAttributeValueByName(Token.ID);
	if(name!=null)
	{
		try{
			setId(name,this);
		}
		catch(LockException le){} //Dummy catch
	}

	XmlElement element;

	for(int loop=0;loop<xml.getElementCount();loop++)
	{
		element = xml.getElementByIndex(loop);
		if(element == null)
			continue;

		String eleName = element.getName();

		if(eleName.equals(Token.GROUP))
		{
			group = new DataStates();
			group.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.RULE))
		{
			rule = new DataString();
			rule.buildFromgrfxML(element);
			setRule();
		}
		else if(super.buildFromElement(element)==false && !NameHelper.isSystemName(element.getName()))
		{
			GrfxMLException.warning( GrfxMLException.WARNING_UNRECOGNISED_TAG_CODE ,new Object[]{eleName,Token.ACTION_SET,""+element.getStartLineNo()} );
		}
	}
}
public void copyFromgrfxML(XmlElement xml)
{
	XmlElement element;

	for(int loop=0;loop<xml.getElementCount();loop++)
	{
		element = xml.getElementByIndex(loop);
		if(element == null)
			continue;

		String eleName = element.getName();

		if(eleName.equals(Token.GROUP))
		{
			group.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.RULE))
		{
			rule.copyFromgrfxML(element);
			setRule();
		}
		else if(super.copyFromElement(element)==false)
		{
			GrfxMLException.warning( GrfxMLException.WARNING_UNRECOGNISED_TAG_CODE ,new Object[]{eleName,Token.ACTION_SET,""+element.getStartLineNo()} );
		}
	}
}
public DataAction getClone() {

	DataActionSet newActionSet = new DataActionSet(parent);

	super.getClonedElements(newActionSet);

	newActionSet.group = group.getClone();
	newActionSet.rule = rule.getClone();

	return newActionSet;
}
public DataAction getClone(String path) {

	DataActionSet newActionSet = new DataActionSet(parent);

	GrfxMLStoreProcessor.setCloneName( path,this,newActionSet );

	super.getClonedElements(path,newActionSet);

	newActionSet.group = group.getClone(path);
 	newActionSet.rule = rule.getClone(path);

	return newActionSet;
}
protected void process()
{
	setRule();

	if(oldGroup==null)
	{
	 try{
		oldGroup = new DataStates();
		for(int loop=0;loop<group.size();loop++)
		{
			oldGroup.add( new DataState(group.get(loop).getValue()) ,this);
		}
	 }catch(LockException le){}
	}

	int changed = -1;
	DataState state=null;
	DataState oldState=null;

	switch(_ruleCode)
	{
		case ProcessConstant.SET_RADIO_CODE:


		changed = -1;
		state=null;
		for(int loop=0;loop<group.size();loop++)
		{
			state = group.get(loop);
			if(state.hasChanged())
			{
				if( state.getValue()==true )
				{
					changed=loop;
					break;
				}
				else
				{
					try{
						state.setValue( true,this );
					}catch(LockException le){}
				}
			}
		}
		if(changed==-1)
		{
			return;
		}

		try{
			for(int loop=0;loop<group.size();loop++)
			{
				if(loop==changed)
					continue;
				group.get(loop).setValue(false,this);
			}
		}
		catch(LockException le){}
		break;

		case ProcessConstant.SET_EXCLUSIVE_CODE:

		changed = -1;
		state=null;
		for(int loop=0;loop<group.size();loop++)
		{
			state = group.get(loop);
			oldState = oldGroup.get(loop);
			if(oldState.getValue()==false && state.getValue()==true )
			{
				try{
					oldState.setValue( true,this );
				}catch(LockException le){}
				changed=loop;
				break;
			}
		}
		if(changed==-1)
		{
			return;
		}

		try{
			for(int loop=0;loop<group.size();loop++)
			{
				if(loop==changed)
					continue;
				group.get(loop).setValue(false,this);
				oldGroup.get(loop).setValue( false,this );
			}
		}
		catch(LockException le){}
		break;

		case ProcessConstant.SET_INCLUSIVE_CODE:

		changed = -1;
		state=null;
		for(int loop=0;loop<group.size();loop++)
		{
			state = group.get(loop);
			if(state.hasChanged() && state.getValue()==true )
			{
				changed=loop;
				break;
			}
		}
		if(changed==-1)
		{
			return;
		}

		try{
			for(int loop=0;loop<group.size();loop++)
			{
				if(loop==changed)
					continue;
				group.get(loop).setValue(true,this);
			}
		}
		catch(LockException le){}

		break;
	}

}
public void register(DataLinker store) {

	super.register(store);

	try{
		store.add(rule,this);
		store.add(group,this);
	}
	catch(LockException le)
	{}//Dummy catch
	group.register(store);
}
public void replace(Field oldObj, Field newObj) {

	replace(oldObj,newObj,false);

}
public void replace(Field oldObj, Field newObj,boolean recursive) {

	super.replace(oldObj,newObj);

	if(group==oldObj)
		group=(DataStates)newObj;

	if(rule==oldObj)
		rule=(DataString)newObj;

	if(recursive)
	{
		group.replace(oldObj,newObj,recursive);
	}
}
public void resetChanged() {
	super.resetChanged();
	group.resetChanged();
	rule.resetChanged();
}
private void setRule() {
	if(rule.hasChanged())
	{
		String value = rule.getValue();
		if(value.equals(ProcessConstant.SET_EXCLUSIVE))
		{
			_ruleCode = ProcessConstant.SET_EXCLUSIVE_CODE;
		}
		else if(value.equals(ProcessConstant.SET_RADIO))
		{
			_ruleCode = ProcessConstant.SET_RADIO_CODE;
		}
		else if(value.equals(ProcessConstant.SET_INCLUSIVE))
		{
			_ruleCode = ProcessConstant.SET_INCLUSIVE_CODE;
		}
	}
}
public String togrfxML(String name) {
	String xml = "<" + name;

	if(!NameHelper.isSystemName(getId()))
	{
		xml += " id=\""+getId()+"\"";
	}

	xml += ">";
	xml += super.togrfxML(name);
	xml += group.togrfxML(Token.GROUP);
	xml += rule.togrfxML(Token.RULE);
	xml += "</" + name + ">\n";
	return xml;
}
public String toString() {
	if (GrfxMLEngine.DEBUG)
		return (togrfxML(DEFAULT_ID.substring(1)));
	String xml = "<" + DEFAULT_ID.substring(1)+"/>";
	return xml;
}
}
